<template>
  <div class="lifecycle-page">
    <h1>onBeforeUpdate 生命周期钩子</h1>
    
    <div class="lifecycle-card">
      <h2>什么是 onBeforeUpdate?</h2>
      <p>onBeforeUpdate 钩子在组件更新前调用，此时组件的数据已更改，但DOM尚未更新。</p>
      
      <div class="code-example">
        <pre><code>
import { ref, onBeforeUpdate } from 'vue'

export default {
  setup() {
    const count = ref(0)
    
    onBeforeUpdate(() => {
      console.log('数据已更改，DOM即将更新')
      // 可以在DOM更新前获取DOM状态
    })
    
    return { count }
  }
}
        </code></pre>
      </div>
    </div>
    
    <div class="lifecycle-card">
      <h2>实际演示</h2>
      <div class="demo-box">
        <p>当前计数: <span ref="countDisplay">{{ count }}</span></p>
        <p>更新前的DOM值: {{ oldDomValue }}</p>
        <p>更新次数: {{ updateCount }}</p>
        <button @click="increment">增加计数</button>
      </div>
    </div>
    
    <div class="lifecycle-card">
      <h2>适用场景</h2>
      <ul>
        <li><strong>获取更新前的DOM状态：</strong>记录更新前的滚动位置、选中状态等</li>
        <li><strong>性能监控：</strong>记录组件更新前的时间戳</li>
        <li><strong>调试：</strong>跟踪组件更新的原因</li>
      </ul>
    </div>
    
    <div class="lifecycle-card">
      <h2>企业实践</h2>
      <p>在实际开发中，onBeforeUpdate的常见用途：</p>
      <ul>
        <li>在表单组件中，记录更新前的字段值，用于比较变化</li>
        <li>在列表组件中，记录更新前的滚动位置，以便在更新后恢复</li>
        <li>在复杂组件中，记录更新前的DOM状态，用于动画或过渡效果</li>
      </ul>
      <p>示例代码：</p>
      <div class="code-example">
        <pre><code>
import { ref, onBeforeUpdate } from 'vue'

export default {
  setup() {
    const listRef = ref(null)
    const items = ref([1, 2, 3])
    let scrollPosition = 0
    
    onBeforeUpdate(() => {
      // 记录更新前的滚动位置
      if (listRef.value) {
        scrollPosition = listRef.value.scrollTop
        console.log('更新前滚动位置:', scrollPosition)
      }
    })
    
    const addItem = () => {
      items.value.push(items.value.length + 1)
      
      // 在下一个更新周期后恢复滚动位置
      setTimeout(() => {
        if (listRef.value) {
          listRef.value.scrollTop = scrollPosition
        }
      }, 0)
    }
    
    return { listRef, items, addItem }
  }
}
        </code></pre>
      </div>
    </div>
    
    <div class="navigation">
      <router-link to="/mounted" class="nav-button">上一个: onMounted</router-link>
      <router-link to="/updated" class="nav-button">下一个: onUpdated</router-link>
    </div>
  </div>
</template>

<script>
import { ref, onBeforeUpdate } from 'vue'

export default {
  name: 'OnBeforeUpdateView',
  setup() {
    const count = ref(0)
    const countDisplay = ref(null)
    const oldDomValue = ref('尚未更新')
    const updateCount = ref(0)
    
    onBeforeUpdate(() => {
      console.log('onBeforeUpdate 被调用')
      updateCount.value++
      
      // 获取更新前的DOM值
      if (countDisplay.value) {
        oldDomValue.value = countDisplay.value.textContent
        console.log('更新前的DOM值:', oldDomValue.value)
      }
    })
    
    const increment = () => {
      count.value++
    }
    
    return {
      count,
      countDisplay,
      oldDomValue,
      updateCount,
      increment
    }
  }
}
</script>

<style scoped>
.lifecycle-page {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

h1 {
  color: #3498db;
  text-align: center;
  margin-bottom: 30px;
}

.lifecycle-card {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

h2 {
  color: #2c3e50;
  margin-bottom: 15px;
}

.code-example {
  background-color: #2c3e50;
  color: #ecf0f1;
  padding: 15px;
  border-radius: 5px;
  overflow-x: auto;
  margin: 15px 0;
}

pre {
  margin: 0;
}

.demo-box {
  background-color: #e8f4fc;
  padding: 15px;
  border-radius: 5px;
  margin: 15px 0;
}

button {
  background-color: #3498db;
  color: white;
  border: none;
  padding: 8px 15px;
  border-radius: 4px;
  cursor: pointer;
  margin-top: 10px;
}

button:hover {
  background-color: #2980b9;
}

ul {
  padding-left: 20px;
}

li {
  margin-bottom: 8px;
}

.navigation {
  display: flex;
  justify-content: space-between;
  margin-top: 30px;
}

.nav-button {
  display: inline-block;
  padding: 10px 20px;
  background-color: #3498db;
  color: white;
  text-decoration: none;
  border-radius: 5px;
  transition: background-color 0.3s;
}

.nav-button:hover {
  background-color: #2980b9;
}
</style>